#include "hls_protocol_operation.h"

#include "./../hls_protocol/hls_m3u8_message.h"
#include "./../hls_protocol/hls_m3u8_parser.h"
#include "./../http_protocol/http_protocol_msg.h"
#include "http_protocol_operation.h"
#include "protocol_operation.h"

#include <cstdint>
#include <cstdio>

std::shared_ptr<ProtocolOperation> HlsProtocolOperationFactory::CreateProtocolOperation()
{
    auto operation = new HlsProtocolOperation();
    return std::shared_ptr<ProtocolOperation>(operation);
}

HlsProtocolOperation::HlsProtocolOperation() : m_http_protocol(HttpProtocolOperation::RESPONSE)
{
    m_hls_parser = new HlsM3u8Parser();
}

HlsProtocolOperation::~HlsProtocolOperation()
{
    if (m_hls_parser)
    {
        delete m_hls_parser;
        m_hls_parser = nullptr;
    }
}

int HlsProtocolOperation::ParserProtocol(const uint8_t * data, int data_length, int & length)
{
    int use_length = 0;
    int result     = m_http_protocol.ParserProtocol(data, data_length, use_length);
    if (result == ProtocolOperation::NEED_DATA)
    {
        length = use_length;
    }
    else if (result == ProtocolOperation::FINISH)
    {
        length        = use_length;
        auto http_msg = m_http_protocol.HttpResponseMsg();
        if (http_msg && http_msg->GetCode() == "200")
        {
            auto body  = http_msg->Body();
            use_length = 0;
            result     = m_hls_parser->Parser(body.data(), body.size(), use_length);
            // printf("parser hls protocol result : %d.\n", result);
            if (result >= 0)
            {
                m_http_code = http_msg->GetCode();
                m_http_note = http_msg->GetNote();
                // printf("http code %s and http note : %s.\n", m_http_code.c_str(), m_http_note.c_str());
            }
            else
            {
                m_http_code = "400";
                m_http_note = "BAD RESPONSE";
            }
            result = ProtocolOperation::FINISH;
        }
        else
        {
            if (http_msg)
            {
                m_http_code = http_msg->GetCode();
                m_http_note = http_msg->GetNote();
                result      = ProtocolOperation::FINISH;
            }
            else
            {
                result = ProtocolOperation::BAD;
            }
        }
    }
    else
    {
        length = data_length;
        result = ProtocolOperation::BAD;
    }
    return result;
}

int HlsProtocolOperation::OpSuccess() const
{
    return m_http_code == "200" ? 1 : -1;
}

HlsM3U8Message * HlsProtocolOperation::M3U8Msg() const
{
    return m_hls_parser->HlsMessage();
}

HttpProtocolOperation * HlsProtocolOperation::HttpProtocolOperate()
{
    return &m_http_protocol;
}

void HlsProtocolOperation::ClearMsg()
{
    m_http_protocol.ClearMsg();
    m_hls_parser->ClearHlsMessage();
    m_http_code = "";
    m_http_note = "";
}
